#include <stdlib.h>
#include "rcu.h"

using namespace nbds;

struct test {
	int a;
};

void rc() {
	rcu_rc<test> x = new test;
	rcu_ptr<test> a = x.lock_write();
	rcu_ptr<test> b = x.lock_write();

	a->a = 5;
	if (!x.release_write(a))
		exit(1);

	const rcu_ptr<test> c = x.lock_read();
	b->a = 8;
	if (x.release_write(b))
		exit(1);

	if (c->a != 5)
		exit(1);

	b = x.lock_write();
	b->a = 9;

	if (c->a != 5)
		exit(1);

	if (!x.release_write(b))
		exit(1);

	x.release_read(c);

	const rcu_ptr<test> d = x.lock_read();

	if (d->a != 9)
		exit(1);
}

void hp() {
	rcu_hp<test> x = new test;
	rcu_ticket<test> t = x.get_ticket();
	rcu_ptr<test> a = t.lock_write();
	rcu_ptr<test> b = t.lock_write();

	a->a = 5;
	if (!t.release_write(a))
		exit(1);

	const rcu_ptr<test> c = t.lock_read();

	b->a = 8;
	if (t.release_write(b))
		exit(1);

	if (c->a != 5)
		exit(1);

	b = t.lock_write();
	b->a = 9;

	if (c->a != 5)
		exit(1);

	if (!t.release_write(b))
		exit(1);

	t.release_read(c);

	const rcu_ptr<test> d = t.lock_read();

	if (d->a != 9)
		exit(1);
}

int main() {
	rc();
	hp();
}
